import * as THREE from 'three-legacy';
import { BufferGeometry, LineSegments, Vector3 } from 'three-legacy';
import { nmAppLog } from '@app-nextmesh/common/utils';
import { ctx2 } from '@app-cad/module';
import { refreshCanvas } from '@app-nextmesh/utils/canvas';
import { drawTriangular } from '@app-nextmesh/utils';

const arrowChange = (
  centerPoint: number[][], // 中心点
  length: number, // 箭头长度
  max: number,
  min: number,
  value: number[],
  direction: string,
  vector: THREE.Vector3Tuple[][],
) => {
  // 中心数组
  const centers: number[][] = centerPoint; // [[0,0,0], [1, 2, 4]]
  // 设置箭头头部参数
  const arrowHeadLength = length; // 箭头头部的长度, 负数箭头向外，正数箭头向内
  const positions = [];
  // 绘制箭头材质
  const lineMaterial = new THREE.LineBasicMaterial({
    color: setColor(direction),
  });
  centers.forEach((center, index) => {
    if (value[index] === 0) {
      return;
    }
    // 获取方向点集合
    const directionGroup: {
      fourDrop: Vector3[];
      planeDirection: number[];
      direction: string;
    } = directionPoint(
      direction,
      arrowHeadLength,
      center,
      vector === undefined ? [] : vector[index],
      value[index],
    );
    // 获取处理所有方向点+中心点
    const dropGroup = directionGroup.fourDrop;
    nmAppLog('dropGroup-------------->:', directionGroup, dropGroup);
    positions.push(
      ...drawLineArrow(
        dropGroup,
        length, // 长度
        directionGroup.planeDirection,
        value[index],
      ),
    );
  });
  nmAppLog('positions------------>:', positions);
  // 是面片、线或点几何体的有效表述。包括顶点位置，面片索引、法相量、颜色值、UV 坐标和自定义缓存属性值。
  // 使用 BufferGeometry 可以有效减少向 GPU 传输上述数据所需的开销。
  const arrowHeadGeometry = new BufferGeometry().setFromPoints(positions);
  // 在若干对的顶点之间绘制的一系列的线。
  const arrowHead = new LineSegments(arrowHeadGeometry, lineMaterial);
  ctx2.cadScene.toolsGroup.add(arrowHead);
  refreshCanvas();
};

// 绘制线和箭头的集合
const drawLineArrow = (
  arrow: Vector3[], // 结果点
  lineLength: number, // 长度 箭头头部的长度, 负数箭头向外，正数箭头向内
  m: number[], // 面向坐标
  fieldValue: number, // 场的拉力或压力数值
) => {
  // 设置箭头头部参数
  const arrowWidth = lineLength / 20; // 箭头头部的宽度
  const planeDirection = new THREE.Vector3().fromArray(m); // 箭头面的朝向
  // 长度 箭头头部的长度, 负数箭头向外，正数箭头向内，后端返回的数据正是拉（外），负数是压（内）所以是相反
  const arrowHeadLength = -lineLength;
  const pointList = [];
  if (fieldValue >= 0) {
    pointList.push(
      ...drawTriangular(
        arrow[0],
        arrow[1],
        arrowWidth,
        arrowHeadLength,
        planeDirection,
      ),
    );
  } else {
    pointList.push(
      ...drawTriangular(
        arrow[0],
        arrow[1],
        arrowWidth,
        arrowHeadLength,
        planeDirection,
      ),
    );
  }
  return pointList;
};

// 方向点
const directionPoint = (
  direction: string,
  arrowHeadLength: number,
  center: number[],
  vector?: any,
  fieldValue?: number,
) => {
  nmAppLog(
    'direction----------->:',
    direction,
    arrowHeadLength,
    vector,
    center,
  );
  // 原点
  const origin = new THREE.Vector3().fromArray(center);
  let fourDrop = [];
  let planeDirection = [];
  switch (direction) {
    case 'x': { // 方向点
      const xx = fieldValue > 0 ? [1, 0, 0] : [-1, 0, 0];
      fourDrop = [
        origin,
        new THREE.Vector3()
          .fromArray(xx)
          .multiplyScalar(arrowHeadLength)
          .add(origin),
      ];

      planeDirection = [0, 1, 0];
      break;
    }
    case 'y': {
      const yy = fieldValue > 0 ? [0, 1, 0] : [0, -1, 0];
      fourDrop = [
        origin,
        new THREE.Vector3()
          .fromArray(yy)
          .multiplyScalar(arrowHeadLength)
          .add(origin),
      ];
      planeDirection = [1, 0, 0];
      break;
    }
    case 'z': {
      const zz = fieldValue > 0 ? [0, 0, 1] : [0, 0, -1];
      fourDrop = [
        origin,
        new THREE.Vector3()
          .fromArray(zz)
          .multiplyScalar(arrowHeadLength)
          .add(origin),
      ];
      planeDirection = [1, 0, 0];
      break;
    }
    case 'x+y':
    case 'x+z':
    case 'y+z':
    case 'x+y+z':
      fourDrop = [
        origin,
        new THREE.Vector3()
          .fromArray(vector)
          .multiplyScalar(arrowHeadLength)
          .add(origin),
      ];
      planeDirection = [0, 1, 0];
      break;
  }
  return {
    fourDrop,
    planeDirection,
    direction,
  };
};

// 设置颜色
const setColor = (direction: string) => {
  let color: number = 0xff0000;
  switch (direction) {
    case 'x':
      color = 0xff0000; // 红
      break;
    case 'y':
      color = 0x33ff66; //绿
      break;
    case 'z':
      color = 0x3399ff; // 深蓝
      break;
    case 'x+y':
      color = 0xffcc00; // 黄
      break;
    case 'y+z':
      color = 0x33ffff; //浅蓝
      break;
    case 'x+z':
      color = 0xff00ff; // 紫
      break;
    case 'x+y+z':
      color = 0x0000ff; // 深蓝
      break;
  }
  return color;
};

export { arrowChange };
